package demo4;

import java.util.Arrays;

public class BankerTestCase {

    static int numProcesses = 5; // 5个进程
    static int numResources = 3; // 3类资源

    static int[] available = {3, 3, 2}; // 系统可用资源

    // 最大需求矩阵 Max[i][j]
    static int[][] max = {
            {7, 5, 3},
            {3, 2, 2},
            {9, 0, 2},
            {2, 2, 2},
            {4, 3, 3}
    };

    // 当前已分配 Allocation[i][j]
    static int[][] allocation = {
            {0, 1, 0},
            {2, 0, 0},
            {3, 0, 2},
            {2, 1, 1},
            {0, 0, 2}
    };

    // Need = Max - Allocation
    static int[][] need = new int[numProcesses][numResources];

    public static void main(String[] args) {
        // 1. 计算 Need
        for (int i = 0; i < numProcesses; i++) {
            for (int j = 0; j < numResources; j++) {
                need[i][j] = max[i][j] - allocation[i][j];
            }
        }


        // 2. 打印当前状态
        printState();

        // 3. 模拟 P1 请求 [1, 0, 2]
        int[] request = {1, 0, 2};
        int pid = 1;

        System.out.println("\nP" + pid + " 请求资源: " + Arrays.toString(request));
        if (requestGranted(pid, request)) {
            System.out.println("请求成功，系统处于安全状态！");
        } else {
            System.out.println("请求失败，系统不安全！");
        }
    }

    // 银行家算法核心逻辑

    static boolean requestGranted(int pid, int[] request) {
        // Step 1: 检查请求 ≤ Need
        for (int i = 0; i < numResources; i++) {
            if (request[i] > need[pid][i]) return false;
        }

        // Step 2: 检查请求 ≤ Available
        for (int i = 0; i < numResources; i++) {
            if (request[i] > available[i]) return false;
        }

        // Step 3: 试探性分配
        for (int i = 0; i < numResources; i++) {
            available[i] -= request[i];
            allocation[pid][i] += request[i];
            need[pid][i] -= request[i];
        }

        // Step 4: 安全性检查
        boolean safe = checkSafety();

        // Step 5: 回滚 or 保留
        if (!safe) {
            for (int i = 0; i < numResources; i++) {
                available[i] += request[i];
                allocation[pid][i] -= request[i];
                need[pid][i] += request[i];
            }
        }

        return safe;
    }

    // 安全性检查算法
    static boolean checkSafety() {
        int[] work = Arrays.copyOf(available, numResources);
        boolean[] finish = new boolean[numProcesses];

        while (true) {
            boolean found = false;
            for (int i = 0; i < numProcesses; i++) {
                if (!finish[i]) {
                    boolean canFinish = true;
                    for (int j = 0; j < numResources; j++) {
                        if (need[i][j] > work[j]) {
                            canFinish = false;
                            break;
                        }
                    }

                    if (canFinish) {
                        for (int j = 0; j < numResources; j++) {
                            work[j] += allocation[i][j];
                        }
                        finish[i] = true;
                        found = true;
                    }
                }
            }

            if (!found) break;
        }

        // 所有进程都能完成，则系统安全
        for (boolean f : finish) {
            if (!f) return false;
        }
        return true;
    }

    static void printState() {
        System.out.println("当前可用资源 Available: " + Arrays.toString(available));
        System.out.println("Allocation:");
        for (int i = 0; i < numProcesses; i++) {
            System.out.println("P" + i + ": " + Arrays.toString(allocation[i]));
        }

        System.out.println("Max:");
        for (int i = 0; i < numProcesses; i++) {
            System.out.println("P" + i + ": " + Arrays.toString(max[i]));
        }

        System.out.println("Need:");
        for (int i = 0; i < numProcesses; i++) {
            System.out.println("P" + i + ": " + Arrays.toString(need[i]));
        }
    }
}
